package com.yhb.service.impl;

import com.yhb.service.VerifyCodeService;
import lombok.extern.log4j.Log4j;
import me.edzh.spring.bootstrap.utils.JSONUtil;
import me.edzh.spring.bootstrap.utils.MathUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

@Service
@Log4j
public class RedisVerifyCodeServiceImpl implements VerifyCodeService {

    private static final String KEY_PREFIX = "verifyCode-";

    private RedisTemplate<String, String> redis;

    @Autowired

    public void setRedis(RedisTemplate<String, String> redis) {
        this.redis = redis;
        this.redis.setKeySerializer(new StringRedisSerializer());
        this.redis.setValueSerializer(new StringRedisSerializer());
    }

    @Override
    public String generateVerifyCode(String number, long expiration, CodeType codeType) {
        String code = (int)(MathUtils.random(1., 9.) * 100000) + "";
        VerifyCodeModel model = new VerifyCodeModel(code, number, codeType);
        redis.boundValueOps(KEY_PREFIX + code).set(JSONUtil.toJson(model), expiration, TimeUnit.MILLISECONDS);
        return code;
    }

    @Override
    public String generateVerifyCode(String number, CodeType codeType) {
        return generateVerifyCode(number, 1000 * 60 * 10, codeType); // 默认10分钟
    }

    @Override
    public boolean verifyCode(String number, String code, CodeType codeType) {
        if (!redis.hasKey(KEY_PREFIX + code)) return false;


        VerifyCodeModel model = JSONUtil.parseJson(redis.boundValueOps(KEY_PREFIX + code).get(), VerifyCodeModel.class);
        if (model.number.equals(number) && model.type == codeType) {
            redis.delete(KEY_PREFIX + code);
            return true;
        } else {
            return false;
        }
    }

    private static class VerifyCodeModel implements Serializable {
        public String verifyCode;
        public String number;
        public CodeType type;
        public String userId;


        public VerifyCodeModel() {
        }

        public VerifyCodeModel(String verifyCode, String number, CodeType type) {
            this.verifyCode = verifyCode;
            this.number = number;
            this.type = type;
        }
    }

}
